// declare function print(arg:string) : string;

declare interface ArkTools{
  timeInUs(arg:any):number
}

let input: number = 3000000;

function GenerateFloatInput(): Float64Array {
  return new Float64Array([1.0, 2.0]);
}

function GenerateBitOpsInput(): Int32Array {
  return new Int32Array([2, 3]);
}

function GenerateIntegerInput(): Int32Array {
  return new Int32Array([2, 4]);
}

function GenerateFakeRandomInteger(): Int32Array {
  let resource: Int32Array = new Int32Array([12, 43, 56, 76, 89, 54, 45, 32, 35, 47, 46, 44, 21, 37, 84]);
  return resource;
}

function GenerateFakeRandomFloat(): Float64Array {
  let resource: Float64Array = new Float64Array([12.2, 43.5, 56.2, 76.6, 89.7, 54.9, 45.2, 32.5, 35.6, 47.2, 46.6, 44.3, 21.2, 37.6, 84.57]);
  return resource;
}

// 浮点计算
function FloatNumAddition() {
  let count: number = 3000000;
  let floatInputs: Float64Array = GenerateFloatInput();
  let f1: number = 1.0 // floatInputs[0];
  let f2: number = 2.0 // floatInputs[1];
  let f3: number = 1.0;
  let resources: Int32Array = GenerateFakeRandomInteger();
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  for (let i: number = 0; i < count; i++) {
    // f3 += f1 + f2; // 86ms
    if ((resources[i % f3 & (resourcesLength - 1)] & 1) == 0) { // 2100ms
      f3 += f1;
    } else {
      f3 += f2;
    }
  }
  let end: number = ArkTools.timeInUs();
  print("FloatNumAddition" + f3);
  let time = (end - start) / 1000
  print("Numerical Calculation - FloatNumAddition:\t"+String(time)+"\tms");
  return time;
}
FloatNumAddition()
// let runner1 = new BenchmarkRunner("Numerical Calculation - FloatNumAddition", FloatNumAddition);
// runner1.run();


function FloatNumSubstraction() {
  let count: number = 3000000;
  let floatInputs: Float64Array = GenerateFloatInput();
  let f1: number = 1.0 // floatInputs[0];
  let f2: number = 2.0 // floatInputs[1];
  let f3: number = 13000000.0;
  let resources: Int32Array = GenerateFakeRandomInteger();
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  for (let i: number = 0; i < count; i++) {
    if ((resources[i % f3 & (resourcesLength - 1)] & 1) == 0) {
      f3 -= f1
    } else {
      f3 -= f2
    }
  }
  let end: number = ArkTools.timeInUs();
  print("FloatNumSubstraction" + f3);
  let time = (end - start) / 1000
  print("Numerical Calculation - FloatNumSubstraction:\t"+String(time)+"\tms");
  return time;
}
FloatNumSubstraction()
// let runner2 = new BenchmarkRunner("Numerical Calculation - FloatNumSubstraction", FloatNumSubstraction);
// runner2.run();

function FloatNumProduction() {
  let count: number = 3000000;
  let floatInputs: Float64Array = GenerateFloatInput();
  let f1: number = 1.0 // floatInputs[0];
  let f2: number = 2.0 // floatInputs[1];
  let f3: number = 1.0;
  let resources: Int32Array = GenerateFakeRandomInteger();
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  for (let i = 0; i < count; i++) {
    if ((resources[i & (resourcesLength - 1)] & 1) == 0) {
      f3 += f3 * f1
    } else {
      f3 += f3 * f2
    }
  }
  let end: number = ArkTools.timeInUs();
  print("FloatNumProduction" + f3);
  let time = (end - start) / 1000
  print("Numerical Calculation - FloatNumProduction:\t"+String(time)+"\tms");
  return time;
}
FloatNumProduction()
// let runner3 = new BenchmarkRunner("Numerical Calculation - FloatNumProduction", FloatNumProduction);
// runner3.run();

function FloatNumDivision() {
  let count: number = 3000000;
  let f3: number = 1.0;
  let resources: Int32Array = GenerateFakeRandomInteger();
  let inputs: Float64Array = GenerateFakeRandomFloat();
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  let inputsLength: number = inputs.length;
  for (let i: number = 0; i < count; i++) {
    if ((resources[i & (resourcesLength - 1)] & 1) == 0) {
      f3 += f3 / inputs[i & (inputsLength - 1)] / 0.1
    } else {
      f3 += f3 / inputs[(i + resources[i & (resourcesLength - 1)]) & (inputsLength - 1)] / 0.1
    }
  }
  let end: number = ArkTools.timeInUs();
  print("FloatNumDivision" + f3);
  let time = (end - start) / 1000
  print("Numerical Calculation - FloatNumDivision:\t"+String(time)+"\tms");
  return time;
}
FloatNumDivision()
// let runner4 = new BenchmarkRunner("Numerical Calculation - FloatNumDivision", FloatNumDivision);
// runner4.run();

// 位运算
function BitOpsAND() {
  let count: number = 30000000;
  let bitInputs: Int32Array = GenerateBitOpsInput();
  let b1: number = 2 // bitInputs[0]; // 10
  let b2: number = 3 // bitInputs[1]; // 11
  let b3: number = 1;
  let resources: Int32Array = GenerateFakeRandomInteger();
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  for (let i: number = 0; i < count; i++) {
    if ((resources[i % b3 & (resourcesLength - 1)] & 1) == 0) {
      b3 = (b3 & b1) + 1
    } else {
      b3 = (b3 & b2) + 1
    }
  }
  let end: number = ArkTools.timeInUs();
  print("BitOpsAND" + b3);
  let time = (end - start) / 1000
  print("Numerical Calculation - BitOpsAND:\t"+String(time)+"\tms");
  return time;
}
BitOpsAND()
// let runner5 = new BenchmarkRunner("Numerical Calculation - BitOpsAND", BitOpsAND);
// runner5.run();

function BitOpsOR() {
  let count: number = 30000000;
  let b1: number = 2 // bitInputs[0]; // 10
  let b2: number = 3 // bitInputs[1]; // 11
  let b3: number = 1;
  let resources: Int32Array = GenerateFakeRandomInteger();
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  for (let i: number = 0; i < count; i++) {
    if ((resources[i % b3 & (resourcesLength - 1)] & 1) == 0) {
      b3 = (b3 | b1) + 1
      // b3 = b3 | resources[i & (resourcesLength - 1)]
    } else {
      b3 = (b3 | b2) + 1
      // b3 = b3 | resources[(i + 5) & (resourcesLength - 1)]
    }
  }
  let end: number = ArkTools.timeInUs();
  print("BitOpsOR" + b3);
  let time = (end - start) / 1000
  print("Numerical Calculation - BitOpsOR:\t"+String(time)+"\tms");
  return time;
}
BitOpsOR()
// let runner6 = new BenchmarkRunner("Numerical Calculation - BitOpsOR", BitOpsOR);
// runner6.run();

function BitOpsXOR() {
  let count: number = 30000000;
  let b3: number = 1;
  let resources: Int32Array = GenerateFakeRandomInteger();
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  for (let i: number = 0; i < count; i++) {
    if (b3 <= 0) {
      b3 = 1
    }
    if ((resources[i % b3 & (resourcesLength - 1)] & 1) == 0) {
      b3 = b3 ^ resources[i & (resourcesLength - 1)]
    } else {
      b3 = b3 ^ resources[(i + 5) & (resourcesLength - 1)]
    }
  }
  let end: number = ArkTools.timeInUs();
  print("BitOpsXOR" + b3);
  let time = (end - start) / 1000
  print("Numerical Calculation - BitOpsXOR:\t"+String(time)+"\tms");
  return time;
}
BitOpsXOR()
// let runner7 = new BenchmarkRunner("Numerical Calculation - BitOpsXOR", BitOpsXOR);
// runner7.run();

function BitOpsNOT() {
  let count: number = 30000000;
  let b1: number = -2;
  let b2: number = -3;
  let b3: number = 1;
  let resources: Int32Array = GenerateFakeRandomInteger();
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  for (let i: number = 0; i < count; i++) {
    if ((resources[i % b3 & (resourcesLength - 1)] & 1) == 0) {
      b3 += ~b1
    } else {
      b3 += ~b2
    }
  }
  let end: number = ArkTools.timeInUs();
  print("BitOpsNOT" + b3);
  let time = (end - start) / 1000
  print("Numerical Calculation - BitOpsNOT:\t"+String(time)+"\tms");
  return time;
}

BitOpsNOT()
// let runner8 = new BenchmarkRunner("Numerical Calculation - BitOpsNOT", BitOpsNOT);
// runner8.run();

function BitOpsShiftLeft() {
  let count: number = 30000000;
  let bitInputs: Int32Array = GenerateBitOpsInput();
  let b1: number = 2 // bitInputs[0]; // 10
  let b3: number = 1;
  let resources: Int32Array = GenerateFakeRandomInteger()
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  for (let i: number = 0; i < count; i++) {
    if ((resources[i % b3 & (resourcesLength - 1)] & 1) == 0) {
      b3 += b1 << 1;
    } else {
      b3 += b1 << 2;
    }
  }
  let end: number = ArkTools.timeInUs();
  print("BitOpsShiftLeft" + b3);
  let time = (end - start) / 1000
  print("Numerical Calculation - BitOpsShiftLeft:\t"+String(time)+"\tms");
  return time;
}
BitOpsShiftLeft()
// let runner9 = new BenchmarkRunner("Numerical Calculation - BitOpsShiftLeft", BitOpsShiftLeft);
// runner9.run();

function BitOpsShiftRight() {
  let count: number = 30000000;
  let bitInputs: Int32Array = GenerateBitOpsInput();
  let b1: number = 2 // bitInputs[0]; // 10
  let b3: number = 1;
  let resources: Int32Array = GenerateFakeRandomInteger()
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  for (let i: number = 0; i < count; i++) {
    if ((resources[i % b3 & (resourcesLength - 1)] & 1) == 0) {
      b3 += b1 >> 1;
    } else {
      b3 += b1 >> 2;
    }
  }
  let end: number = ArkTools.timeInUs();
  print("BitOpsShiftRight" + b3);
  let time = (end - start) / 1000
  print("Numerical Calculation - BitOpsShiftRight:\t"+String(time)+"\tms");
  return time;
}
BitOpsShiftRight()
// let runner10 = new BenchmarkRunner("Numerical Calculation - BitOpsShiftRight", BitOpsShiftRight);
// runner10.run();


// 整数计算
function IntegerNumAddition() {
  let count: number = 30000000;
  let IntegerInputs: Int32Array = GenerateIntegerInput();
  let resources: Int32Array = GenerateFakeRandomInteger();
  let i1: number = 2// IntegerInputs[0];
  let i2: number = 4// IntegerInputs[1];
  let i3: number = resources[0];
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  for (let i: number = 0; i < count; i++) {
    if ((resources[i % i3 & (resourcesLength - 1)] & 1) == 0) { // 1.07ms
      i3 += i1
    } else {
      i3 += i2
    }
  }
  let end = ArkTools.timeInUs();
  // print("IntegerNumAddition" + i3);
  let time = (end - start) / 1000
  print("Numerical Calculation - IntegerNumAddition:\t"+String(time)+"\tms");
  return time;
}
IntegerNumAddition()
// print("IntegerNumAddition time: " + IntegerNumAddition())
// let runner12 = new BenchmarkRunner("Numerical Calculation - IntegerNumAddition", IntegerNumAddition);
// runner12.run();


function IntegerNumSubstraction() {
  let count: number = 30000000;
  let IntegerInputs: Int32Array = GenerateIntegerInput();
  let i1: number = 2 // IntegerInputs[0];
  let i2: number = 4 // IntegerInputs[1];
  let i3: number = 130000000;
  let resources: Int32Array = GenerateFakeRandomInteger()
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  for (let i: number = 0; i < count; i++) {
    if ((resources[i % i3 & (resourcesLength - 1)] & 1) == 0) { // 1.07ms
      i3 -= i1
    } else {
      i3 -= i2
    }
  }
  let end: number = ArkTools.timeInUs();
  print("IntegerNumSubstraction" + i3);
  let time = (end - start) / 1000
  print("Numerical Calculation - IntegerNumSubstraction:\t"+String(time)+"\tms");
  return time;
}
IntegerNumSubstraction()
// console.log("IntegerNumSubs time: " + IntegerNumSubstraction());
// let runner13 = new BenchmarkRunner("Numerical Calculation - IntegerNumSubstraction", IntegerNumSubstraction);
// runner13.run();

function IntegerNumProduction() {
  let count: number = 30000000;
  let i3: number = 1;
  let resources: Int32Array = GenerateFakeRandomInteger();
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length - 1;
  for (let i: number = 0; i < count; i++) {
    if ((resources[i % i3 & resourcesLength] & 1) == 0) { // ark:21ms node:4ms
      i3 *= 3 // resources[i & resourcesLength]
    } else {
      i3 *= 2 // resources[(i + 5) & resourcesLength]
    }
    if (i3 > 10000000) {
      i3 = 1
    }
  }
  let end: number = ArkTools.timeInUs();
  print("IntegerNumProduction" + i3);
  let time = (end - start) / 1000
  print("Numerical Calculation - IntegerNumProduction:\t"+String(time)+"\tms");
  return time;
}
IntegerNumProduction()
// let runner14 = new BenchmarkRunner("Numerical Calculation - IntegerNumProduction", IntegerNumProduction);
// runner14.run();


function IntegerNumDivision() {
  let count: number = 30000000;// input;
  let i1: number = 2 // IntegerInputs[0];
  let i2: number = 4 // IntegerInputs[1];
  let i3: number = 32768;
  let resources: Int32Array = GenerateFakeRandomInteger();
  // let results: number[] = [0, 0, 0, 0, 0];
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  for (let i: number = 0; i < count; i++) {
    if (i3 <= 4) {
      i3 = 32768;
    }
    if ((resources[i % i3 & (resourcesLength - 1)] & 1) == 0) { // ark:21ms node:4ms
      // i3 += i2 / i1
      i3 = i3 / i1
      // results[i % 5] = i2 / i1
    } else {
      // i3 += i2 / i1 / 2
      i3 = i3 / i2
      // results[i % 5] = i2 / i1 / 2
    }

  }
  let end: number = ArkTools.timeInUs();
  // for (let i = 0; i < 5; i++) {
  // i3 += results[i];
  // }
  print("IntegerNumDivision" + i3);
  let time = (end - start) / 1000
  print("Numerical Calculation - IntegerNumDivision:\t" + String(time) + "\tms");
  return time;
}
IntegerNumDivision()
// let runner15 = new BenchmarkRunner("Numerical Calculation - IntegerNumDivision", IntegerNumDivision);
// runner15.run();


// 浮点数比较
function FloatNumComparision() {
  let count: number = 3000000; // input;
  let resources: Float64Array = GenerateFakeRandomFloat();
  let res: number = 1;
  let start: number = ArkTools.timeInUs();
  let resourcesLength: number = resources.length;
  for (let i: number = 0; i < count; i++) {
    let next_index: number = i + 5
    let next_res: number = res + 1
    if (resources[i % res & (resourcesLength - 1)] > resources[next_index % next_res & (resourcesLength - 1)]) {
      res += 1
    } else {
      res += 2
    }
  }
  let end: number = ArkTools.timeInUs();
  print("FloatNumComparision" + res);
  let time = (end - start) / 1000
  print("Numerical Calculation - FloatNumComparision:\t"+String(time)+"\tms");
  return time;
}
FloatNumComparision()
// let runner16 = new BenchmarkRunner("Numerical Calculation - FloatNumComparision", FloatNumComparision);
// runner16.run();

// String运算
function StringCalculation() {
  let count: number = 3000000 / 1000;
  let str1: string = "h";
  let res: string = "11";
  let resources: Int32Array = GenerateFakeRandomInteger();
  let start: number = ArkTools.timeInUs();
  for (let i: number = 0; i < count; i++) {
    if (resources[i % res.length % 15] > resources[(i + resources[i % 15]) % res.length % 15]) {
      res += str1 + i;
    } else {
      res += str1;
//       res += str1;
    }
  }
  let end: number = ArkTools.timeInUs();
  print(""+res.length);
  let time = (end - start) / 1000
  print("Numerical Calculation - StringCalculation:\t"+String(time)+"\tms");
  return time;
}
StringCalculation()
// let runner18 = new BenchmarkRunner("Numerical Calculation - StringCalculation", StringCalculation);
// runner18.run();